home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / wstype / source / keyin.c < prev    next >
C/C++ Source or Header  |  1991-10-18  |  5KB  |  242 lines

  1. /***   [keyin.c]
  2. *
  3. *    キーボード入力        (C)ささがわ
  4. *
  5. *    For GNU C Compiler (GCC)   Version 1.39
  6. *
  7. ***/
  8.  
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include "graph.h"
  13. #include "kyb.h"
  14. #include "mos.h"
  15. #include "keyin.h"
  16.  
  17. #define KEY_BUFSIZ    255        /* バッファサイズ */
  18. #define KEY_ROLLSPD    8        /* スクロール・スピード 1 2 4 8 */
  19.  
  20. /* 関数プロトタイプ宣言 */
  21. static void Curonoff(int);
  22. static void bufins(char);
  23. static void bufdel(void);
  24. static void bufbks(void);
  25. static void shift(int, int, int);
  26. static char gputc(int);
  27.  
  28. /* グローバル変数宣言 */
  29. static char    buf[KEY_BUFSIZ + 1];    /* バッファ宣言 */
  30. static int    len;    /*    文字列の長さ                0 <= x <= KEY_BUFSIZ    */
  31. static int    cur;    /*    ビューボックス中のカーソルの位置        0 <= x <= kt->keta - 1    */
  32. static int    start;    /*    バッファ中のビューボックスの位置    0 <= x <= len - cur        */
  33. static struct keyin_t    *kt;    /* 環境構造体 */
  34.  
  35. /* 初期化関数(グローバル) */
  36. void Keyin_init(struct keyin_t *keyt) {
  37.     len = 0;
  38.     start = 0;
  39.     cur = 0;
  40.     kt = keyt;
  41.     MOS_disp(0);
  42.     EGB_boxf(kt->x, kt->y - 15, kt->x + kt->keta * 8 - 1, kt->y, kt->backC, kt->backC);
  43.     Curonoff(1);
  44.     MOS_disp(1);
  45.     KYB_clrbuf();
  46. }
  47.  
  48. /* 再表示関数(グローバル) */
  49. void Keyin_redisp(void) {
  50.     int        i;
  51.     
  52.     MOS_disp(0);
  53.     for (i = 0; i < kt->keta; i++)
  54.         gputc(i);
  55.     Curonoff(1);
  56.     MOS_disp(1);
  57. }
  58.  
  59. /* カーソル移動関数(グローバル) */
  60. int Keyin_cur(int cr) {
  61.     if (cr < 0 || kt->keta <= cr)
  62.         return -1;
  63.     
  64.     if (cr > len - start)
  65.         cr = len - start;
  66.     if (cur != cr) {
  67.         MOS_disp(0);
  68.         Curonoff(0);
  69.         cur = cr;
  70.         Curonoff(1);
  71.         MOS_disp(1);
  72.     }
  73.     
  74.     return cur;
  75. }
  76.  
  77. /***
  78. *    メイン関数(グローバル)
  79. *       戻り値  0:正常終了   1:入力完了   -1:中断
  80. ***/
  81. int Keyin(void) {
  82.     int            ret;
  83.     unsigned    kadr, kcode;
  84.     
  85.     if ((kcode = KYB_read(1, &kadr)) == 0xffff) {
  86.         ret = 0;
  87.     } else if (kcode == 0x1b) {
  88.         ret = -1;                /* 中断 */
  89.     } else if (kcode == 0x0d) {
  90.         buf[len] = '\0';
  91.         buf[kt->bufn - 1] = '\0';
  92.         strcpy(kt->buf, buf);    /* 入力完了 */
  93.         ret = 1;
  94.     } else {
  95.         MOS_disp(0);
  96.         Curonoff(0);
  97.         
  98.         if (kcode == 0x1c) {    /* [→] */
  99.             KYB_clrbuf();    /* カーソルの惰性防止 */
  100.             if (start + cur == len || (len == KEY_BUFSIZ && start + cur >= len - 1)) {
  101.                 /* カーソルが、文字列かバッファの末尾にあるならば */
  102.                 ;
  103.             } else if (cur == kt->keta - 1) {
  104.                 /* カーソルがビューボックスの末尾にあるならば */
  105.                 start++;
  106.                 shift(0, kt->keta - 1, -1);
  107.             } else {
  108.                 cur++;
  109.             }
  110.         } else if (kcode == 0x1d) {        /* [←] */
  111.             KYB_clrbuf();    /* カーソルの惰性防止 */
  112.             if (start + cur == 0) {
  113.                 /* カーソルがバッファの先頭にあるならば */
  114.                 ;
  115.             } else if (start > 0 && cur == 1) {
  116.                 /* ビューボックスがバッファの先頭を表示しておらず、カーソルが1の位置にあるならば */
  117.                 start--;
  118.                 shift(0, kt->keta - 1, 1);
  119.             } else {
  120.                 cur--;
  121.             }
  122.         } else if (kcode == 0x08) {        /* [バックスペース] */
  123.             KYB_clrbuf();    /* カーソルの惰性防止 */
  124.             if (start + cur == 0) {
  125.                 /* カーソルがバッファの先頭にあるならば */
  126.                 ;
  127.             } else if (start > 0 && cur == 1) {
  128.                 /* ビューボックスがバッファの先頭を表示しておらず、カーソルが1の位置にあるならば */
  129.                 bufbks();
  130.                 start--;
  131.                 gputc(0);
  132.             } else {
  133.                 bufbks();
  134.                 shift(--cur, kt->keta - 1, -1);
  135.             }
  136.         } else if (kcode == 0x7f) {        /* [削除] */
  137.             KYB_clrbuf();    /* カーソルの惰性防止 */
  138.             if (start + cur < len) {
  139.                 /* カーソルが文字列中にあるならば */
  140.                 bufdel();
  141.                 shift(cur, kt->keta - 1, -1);
  142.             }
  143.         } else if (kcode < 0x100 && !iscntrl(kcode)) {
  144.             bufins(kcode);
  145.             if (cur == kt->keta - 1) {
  146.                 /* カーソルがビューボックスの末尾にあるならば */
  147.                 gputc(cur);
  148.                 if (len != KEY_BUFSIZ || start + cur < len - 1) {
  149.                     /* カーソルがバッファの末尾にないならば */
  150.                     start++;
  151.                     shift(0, cur, -1);
  152.                 }
  153.             } else {
  154.                 shift(cur++, kt->keta - 1, 1);
  155.             }
  156.         }
  157.         
  158.         Curonoff(1);
  159.         MOS_disp(1);
  160.         
  161.         ret = 0;
  162.     }
  163.     
  164.     return ret;
  165. }
  166.  
  167. /* カーソル表示・非表示関数 */
  168. static void Curonoff(int sw) {
  169.     switch (sw) {
  170.         case 0:
  171.             gputc(cur);
  172.             break;
  173.         
  174.         case 1:
  175.             EGB_box(kt->x + 8 * cur, kt->y - 15, kt->x + 8 * cur + 1, kt->y, kt->curC);
  176.             break;
  177.     }
  178. }
  179.  
  180. /* 一文字挿入関数 (位置:start + cur) */
  181. static void bufins(char c) {
  182.     int    i;
  183.     
  184.     for (i = len - 1; i >= start + cur; i--)
  185.         buf[i + 1] = buf[i];
  186.     buf[start + cur] = c;
  187.     len++;
  188.     if (len >= KEY_BUFSIZ)
  189.         len = KEY_BUFSIZ;
  190. }
  191.  
  192. /* 一文字削除関数 */
  193. static void bufdel(void) {
  194.     int    i;
  195.     
  196.     for (i = start + cur + 1; i <= len - 1; i++)
  197.         buf[i - 1] = buf[i];
  198.     len--;
  199. }
  200.  
  201. /* バックスペース関数 */
  202. static void bufbks(void) {
  203.     int    i;
  204.     
  205.     for (i = start + cur; i <= len - 1; i++)
  206.         buf[i - 1] = buf[i];
  207.     len--;
  208. }
  209.  
  210. /* 左右スクロール関数 */
  211. static void shift(int from, int to, int dir) {
  212.     int        i;
  213.     
  214.     if (dir >= 0) {
  215.         for (i = 0; i < 8 / KEY_ROLLSPD; i++)
  216.             EGB_scrl(0, kt->x + 8 * from, kt->y - 15, kt->x + 8 * to + 7, kt->y, KEY_ROLLSPD, 0);
  217.         gputc(from);
  218.     } else if (dir < 0) {
  219.         for (i = 0; i < 8 / KEY_ROLLSPD; i++)
  220.             EGB_scrl(0, kt->x + 8 * from, kt->y - 15, kt->x + 8 * to + 7, kt->y, -KEY_ROLLSPD, 0);
  221.         gputc(to);
  222.     }
  223. }
  224.  
  225. /* 一文字表示関数 (k:カーソル位置) */
  226. static char gputc(int k) {
  227.     char    str[5];
  228.     
  229.     EGB_writeMode(EGB_work, 9);
  230.     EGB_color(EGB_work, EGB_COL_BACK, kt->backC);
  231.     
  232.     if (start + k >= len)
  233.         str[0] = ' ';
  234.     else
  235.         str[0] = buf[start + k];
  236.     str[1] = 0;
  237.     EGB_str(str, kt->x + 8 * k, kt->y, kt->foreC);
  238.     
  239.     EGB_writeMode(EGB_work, 0);
  240.     return str[0];
  241. }
  242.